/*   Carina
 *   Copyright (C) 2009 2010 2011  Zdravko Velinov
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "color-picker-button.hh"

#include <QStyleOption>
#include <QKeyEvent>
#include <QPainter>

#include <cassert>

// TODO: eye candies, debugging, Q_D

ColorPickerButton::ColorPickerButton(QWidget* parent)
    :   QWidget(parent, Qt::Widget),
        m_Color(0, 0, 0),
        m_Raised(QStyle::State_Raised)
{
    setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
    setFocusPolicy(Qt::TabFocus);
}

ColorPickerButton::ColorPickerButton(QColor& color, QWidget* parent)
    :   QWidget(parent, Qt::Widget)
{
    setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    setFocusPolicy(Qt::TabFocus);
}

QSize ColorPickerButton::sizeHint() const
{
    return QSize(50, 25);
}

void ColorPickerButton::setColor(const QColor& color)
{
    m_Color = color;
}

QColor ColorPickerButton::getColor() const
{
    return m_Color;
}

void ColorPickerButton::paintEvent(QPaintEvent* evt)
{
    int margin = 7, margin_focus = 5;
    QRect rect = this->rect();
    QPainter p(this);
    {
    QStyleOptionButton opt;
    opt.palette = palette();
    opt.rect = rect;
    opt.features = QStyleOptionButton::DefaultButton;
    if(isEnabled())
        opt.state = QStyle::State_Enabled | m_Raised;
    if(m_Raised == QStyle::State_Sunken)
        opt.state = QStyle::State_Enabled | m_Raised;
    style()->drawControl(QStyle::CE_PushButtonBevel, &opt, &p, this);
    }

    {
    QStyleOptionFrame opt;
    int lw = opt.lineWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
    opt.midLineWidth = 1;
    opt.rect = rect.adjusted(margin, margin, -margin, -margin);
    opt.palette = palette();
    opt.state = QStyle::State_Enabled | QStyle::State_Sunken;
    style()->drawPrimitive(QStyle::PE_Frame, &opt, &p, this);

    assert(m_Color.isValid());
    p.fillRect(opt.rect.adjusted(lw, lw, -lw, -lw), m_Color);
    }

    if(hasFocus())
    {
        QStyleOptionFocusRect opt;
        opt.palette = palette();
        opt.rect = rect.adjusted(margin_focus, margin_focus, -margin_focus, -margin_focus);
        opt.state = QStyle::State_None | QStyle::State_KeyboardFocusChange;
        style()->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, &p, this);
    }
}

void ColorPickerButton::keyPressEvent(QKeyEvent* evt)
{
    if(evt->key() == Qt::Key_Space)
    {
        m_Raised = QStyle::State_Sunken;
        update();
    }
    else
        evt->ignore();
}

void ColorPickerButton::keyReleaseEvent(QKeyEvent* evt)
{
    if(evt->key() == Qt::Key_Space)
    {
        m_Raised = QStyle::State_Raised;
        update();
        emit clicked();
    }
    else
        evt->ignore();
}

void ColorPickerButton::mousePressEvent(QMouseEvent* evt)
{
    if(evt->button() == Qt::LeftButton)
    {
        m_Raised = QStyle::State_Sunken;
        update();
    }
}

void ColorPickerButton::mouseReleaseEvent(QMouseEvent* evt)
{
    if(evt->button() == Qt::LeftButton)
    {
        m_Raised = QStyle::State_Raised;
        update();
        emit clicked();
    }
}